// ... 源码 有缩减

// 函数每次执行都会返回全新data对象实例

function initData (vm: Component) {
  let data = vm.$options.data

  // 如果data是函数，则执行并将其结果作为data选项的值
  data = vm._data = typeof data === 'function'
    // #7573 disable dep collection when invoking data getters
    // 抠脚翻译：调用数据获取程序时禁用dep收集
    ? getData(data, vm) // 实例 data 进行了什么操作？ `pushTarget`
    : data || {} // 用户 data
  if (!isPlainObject(data)) {
    data = {}
    process.env.NODE_ENV !== 'production' && warn(
      'data functions should return an object:\n' +
      'https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function',
      vm
    )
  }
  // proxy data on instance
  // 代理这些数据到实例上
  const keys = Object.keys(data)
  const props = vm.$options.props
  const methods = vm.$options.methods
  let i = keys.length
  while (i--) {
    const key = keys[i]
    if (process.env.NODE_ENV !== 'production') {
      if (methods && hasOwn(methods, key)) {
        warn(
          `Method "${key}" has already been defined as a data property.`,
          vm
        )
      }
    }
    if (props && hasOwn(props, key)) {
      process.env.NODE_ENV !== 'production' && warn(
        `The data property "${key}" is already declared as a prop. ` +
        `Use prop default value instead.`,
        vm
      )
    } else if (!isReserved(key)) {
      proxy(vm, `_data`, key)
    }
  }
  // observe data
  observe(data, true /* asRootData */)
}

// ...